#include <cstdint>
#include <cstdio>
#include <deque>
#include <iostream>
#include <istream>
using ll = int64_t;

#define sl static inline

const ll maxn = 1005;
ll n, m;
int a[maxn][maxn];
bool vis[maxn][maxn][4][2];
int dir[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
struct Q {
    Q(ll s, ll x, ll y, ll dir, bool is2) : s(s), x(x), y(y), dir(dir), is2(is2) {
    }
    ll s, x, y, dir;
    bool is2;
};
std::deque<Q> q;

sl bool check(ll x, ll y, ll dir, bool is2) {
    if (x < 1 || x > n || y < 1 || y > m)
        return false;
    if (a[x][y] == 0)
        return false;
    if (a[x][y] == 3 && !is2)
        return false;
    return !vis[x][y][dir][is2];
}

int main() {
    std::iostream::sync_with_stdio(false);
    std::cin.tie(nullptr);

    std::cin >> n >> m;
    for (ll i = 1; i <= n; i++) {
        for (ll j = 1; j <= m; j++) {
            std::cin >> a[i][j];
        }
    }

    q.emplace_back(0, 1, 1, 0, false);
    vis[1][1][0][false] = true;

    while (q.size()) {
        auto [s, x, y, dd, is2] = q.front();
        q.pop_front();

        if (x == n && y == m) {
            std::cout << s << "\n";
            return 0;
        }
        
        if (a[x][y] == 4 && check(x+dir[dd][0], y+dir[dd][1], dd, is2)) {
            ll nx = x + dir[dd][0], ny = y + dir[dd][1];
            bool nis2 = (a[nx][ny] == 2);
            if (!check(nx, ny, dd, is2))
                continue;

            vis[nx][ny][dd][nis2] = true;

            q.emplace_back(s + 1, nx, ny, dd, nis2);
            continue;
        }

        for (ll i = 0; i < 4; i++) {
            ll nx = x + dir[i][0], ny = y + dir[i][1];

            if (nx < 1 || nx > n || ny < 1 || ny > m)
                continue;

            bool nis2 = is2;
            if (a[nx][ny] == 2)
                nis2 = true;
            if (a[nx][ny] == 4)
                nis2 = false;

            if(a[nx][ny]==4){
                if (!check(nx, ny, i, is2))
                    continue;
                vis[nx][ny][i][nis2] = true;
                q.emplace_back(s + 1, nx, ny, i, nis2);
            }else{
                if(!check(nx, ny, 0, is2))
                    continue;
                vis[nx][ny][0][nis2] = true;
                q.emplace_back(s + 1, nx, ny, 0, nis2);
            }
        }
    }
    std::cout << "-1\n";
}